<?php
namespace app\admin\controller;

use app\admin\controller\Common;
use think\Db;
use PHPExcel_IOFactory;
use think\facade\Env;
use PHPQRCode\QRcode;

class Cert extends Common
{
    public $think;
    public $canvas;

    public function __construct()
    {
        parent::__construct();
        $this->think = $_SESSION['think'];
        $https = $this->is_https();
        $_SERVER['HOST'] = $https ? 'https://' : 'http://' . $_SERVER['SERVER_NAME'] . DIRECTORY_SEPARATOR;
    }
    /*
      *证书生成的默认配置
     */
    public function canvasDefault($cert_img){
        list($width, $height) = getimagesize($cert_img);
        $this->canvas = [
            //生成text图片设置
            'text' => [
                'width'  => $width,  //文本图宽（对应证书模板）
                'height' => $height, //文本图高（对应证书模板）
                'color'  => ['red' => 255, 'green' => 255, 'blue' => 255], //文本颜色
                'type'   => [
                    [//类型一(姓名+成绩)
                        'group'  => ['x'=> 700,'y' => 0],
                        'name'   => ['x'=> 700,'y' => 930],
                        'number' => ['x'=> 700,'y' => 0],
                        'grade'  => ['x'=> 700,'y' => 1140],
                    ],
                    [//类型二(号码+成绩)
                        'group'  => ['x'=> 700,'y' => 0],
                        'name'   => ['x'=> 700,'y' => 0],
                        'number' => ['x'=> 700,'y' => 930],
                        'grade'  => ['x'=> 700,'y' => 1140],
                    ],
                    [//类型三(姓名+号码+成绩)
                        'group'  => ['x'=> 700,'y' => 0],
                        'name'   => ['x'=> 700,'y' => 900],
                        'number' => ['x'=> 700,'y' => 1120],
                        'grade'  => ['x'=> 700,'y' => 1340],
                    ],
                    [//类型四(组别+姓名+号码+成绩)
                        'group'  => ['x'=> 700,'y' => 830],
                        'name'   => ['x'=> 700,'y' => 1000],
                        'number' => ['x'=> 700,'y' => 1200],
                        'grade'  => ['x'=> 700,'y' => 1370],
                    ],
                ],

            ],
            //合并时生成的图片像素设置
            'merge' => [
                'width'  => $width,  //文本图宽（对应证书模板）
                'height' => $height, //文本图高（对应证书模板）
            ]
        ];
    }
    /*
     *活动列表
    */
    function certList()
    {
        $inputData = input('get.');
        $res = $list = array();
        $p = empty($_GET['p']) ? 1 : $_GET['p'];
        $size = empty($_REQUEST['size']) ? 25 : $_REQUEST['size'];
        $where = 'id > 0';
        if ($this->think['admin_id'] > 1) {
            $where = 'admin_id = ' . $this->think['admin_id'];
        }
        if ($inputData['keyword']) {
            $where .= " and title like '%" . $inputData['keyword'] . "%'";
            $this->assign('keyword', $inputData['keyword']);
        }
        $count = Db::name('cert')->where($where)->count();// 查询满足要求的总记录数
        $res = Db::name('cert')->where($where)->order('id desc')->paginate($size, $count, ['query' => request()->param()])->each(function ($item, $key) {
            $item['url'] = $_SERVER['HOST'] . 'index.php' . DIRECTORY_SEPARATOR . 'home' . DIRECTORY_SEPARATOR . 'Cert' . DIRECTORY_SEPARATOR . 'mobile.html?id=' . $item['id'];
            $path = Env::get('root_path') . 'userfiles' . DIRECTORY_SEPARATOR . 'qrcode' . DIRECTORY_SEPARATOR;
            $item['code'] = $_SERVER['HOST'] . 'userfiles' . DIRECTORY_SEPARATOR . 'qrcode' . DIRECTORY_SEPARATOR . $this->codeCreate($item['url'],
                    $path, $item['id']);
            return $item;
        });
        $page = $res->render();
        $this->assign('list', $res);// 赋值数据集
        $this->assign('page', $page);// 赋值分页输出
        $this->assign('total', $count);// 数据总数

        return view('certList');
    }

    function is_https()
    {
        if (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') {
            return true;
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
            return true;
        } elseif (!empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off') {
            return true;
        } else {
            return false;
        }
    }

    function qrcode()
    {
        $id = input('route.id');
        $code = $_SERVER['HOST'] . 'userfiles' . DIRECTORY_SEPARATOR . 'qrcode' . DIRECTORY_SEPARATOR . $id . '.png';
        $this->assign('code', $code);
        return view('code');
    }

    // 生成二维码图片
    public function codeCreate($url, $path, $disid)
    {
        //设置页面等待时间
        set_time_limit(0);
        // 头部编号为utf8
        // header('Content-Type: text/html;charset=utf-8');
        //引入二维码生成插件
        // 生成的二维码所在目录+文件名
        // $path = 'Codezip/'.$random.'/';

        //生成的二维码所在目录
        if (!is_dir($path)) {
            mkdir(iconv("UTF-8", "GBK", $path), 0777, true);
        }
        //生成的二维码文件名
        $pngname = $disid . '.png';
        //1.拼装生成的二维码文件路径
        $fileName = $path . $pngname;
        //3.纠错级别：L、M、Q、H
        $level = 'L';
        //4.点的大小：1到10, 用于手机端4就可以了
        $size = 6;
        //清空缓冲区
        ob_end_clean();
        // ob_start();
        // 生成二维码
        QRcode::png($url, $fileName, $level, $size);
        return $pngname;

    }

    /*
       *编辑信息
      */
    public function cert()
    {
        $act = input('route.act') ? input('route.act') : 'add';
        $info = array();
        if (input('route.id')) {
            $id = input('route.id');
            $info = db('cert')->where('id=' . $id)->find();
            $date = $info['updated_at'];
        } else {
            $date = date('Y-m-d H:i:s', $_SERVER['REQUEST_TIME']);
        }

        $this->assign('act', $act);
        $this->assign('info', $info);
        $this->assign('date', $date);// 赋值数据集
        return view();
    }

    /*
    *活动处理
   */
    public function certHandle()
    {
        $data = $this->certVerify(input('post.'));
        if (!empty($data['errcode'])) {
            $json = array('status' => 0, 'message' => $data['message']);
            echo json_encode($json);
            exit;
        }
        $act = $data['act'];
        $data['updated_at'] = date('Y-m-d H:i:s', time());
        unset($data['act']);
        if ($act == 'add') {
            $data['admin_id'] = $this->think['admin_id'];
            $data['created_at'] = date('Y-m-d H:i:s', time());
            $r = db('cert')->insertGetId($data);
            if ($r) {
                $json['status'] = 1;
                $json['message'] = lang('success');
                /*********************记录日志***********************/
                addLog(session('user_name') . '添加活动成功-' . $data['title'] . ' [ ID:' . $r . ' ]');
                echo json_encode($json);
                exit;
            } else {
                $json['status'] = 0;
                $json['message'] =lang('fail');
                echo json_encode($json);
                exit;
            }
        }

        if ($act == 'edit') {
            $id = $data['id'];
            unset($data['id']);
            try {
                $r = db('cert')->where('id=' . $id)->update($data);
            } catch (ValidateException $e) {
                // 这是进行验证异常捕获
                return json($e->getError());
            } catch (\Exception $e) {
                // 这是进行异常捕获
                return json($e->getMessage());
            }
            // dump($article_id);exit;
            if ($r !== false) {
                $json['status'] = 1;
                $json['message'] = lang('success');
                /*********************记录日志***********************/
                addLog(session('user_name') . '修改活动成功-' . $data['title'] . ' [ ID:' . $data['article_id'] . ' ]');
                echo json_encode($json);
                exit;
            } else {
                $json['status'] = 0;
                $json['message'] = lang('fail');
                echo json_encode($json);
                exit;
            }

        }

    }

    /*
   *信息验证
  */
    function certVerify($data)
    {
        if (empty($data['title'])) {
            $data = array('errcode' => 1, 'message' => lang('title_empty'));
        }
        if (empty($data['cert_img'])) {
            $data = array('errcode' => 1, 'message' => lang('cert_empty'));
        }
        if (empty($data['cert_type'])) {
            $data = array('errcode' => 1, 'message' => lang('mode_empty'));
        }
        if (empty($data['cert_file'])) {
            $data['cert_file'] = time() . mt_rand(1, 1000000);
        }
        if (!empty($data['excel'])) {
            $res = $this->importExcel($data);
            if (!$res) {
                $data = array('errcode' => 1, 'message' => lang('excel_empty'));
            }
        }
        return $data;
    }

    /*
       **复制活动
       */
    function certcopy()
    {
        $id = input('post.id');
        $data = db("Cert")->where(array('id' => $id))->find();
        unset($data['id']);
        $re = db("Cert")->insertGetId($data);
        if ($re !== false) {
            $json['status'] = 1;
            $json['message'] = lang('success');
            /*********************记录日志***********************/
            // addLog(session('user_name').'复制活动成功-'.$data['title'].' [ ID:'.$data['article_id'].' ]');
        } else {
            $json['status'] = 0;
            $json['message'] = lang('fail');
        }
        echo json_encode($json);
        return;
    }

//导入表格
    public function importExcel($arr)
    {
        //获取上传到后台的文件名
        $fileName = $arr['excel'];
        //获取文件路径
        $filePath = Env::get('root_path') . $fileName;
        //获取文件后缀
        $suffix = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
        $xlsx = ['xlsx', 'xlsm', 'xltx', 'xltm'];
        $xls = ['xls', 'xlt'];
        $res = 0;
        //判断哪种类型
        if (in_array($suffix, $xlsx)) {
            $reader = \PHPExcel_IOFactory::createReader('Excel2007');
            $res = 1;
        }
        if (in_array($suffix, $xls)) {
            $reader = \PHPExcel_IOFactory::createReader('Excel5');
            $res = 1;
        }
        if ($res == 0) {
            return false;
        }
        //默认图片证书设置
        if ($this->think['admin_id'] > 0){
            $this->canvasDefault(Env::get('root_path') . $arr['cert_img']);
        }
        //载入excel文件
        $excel = $reader->load("$filePath", $encode = 'utf-8');
        //读取第一张表
        $sheet = $excel->getSheet(0);
        //获取总行数
        $row_num = $sheet->getHighestRow();
        //获取总列数
        $col_num = $sheet->getHighestColumn();
        $file_path = Env::get('root_path') . 'userfiles' . DIRECTORY_SEPARATOR . 'cert' . DIRECTORY_SEPARATOR . $arr['cert_file'];
        if (is_dir($file_path)) {
            $this->delDir($file_path);
        }
        if (!is_dir($file_path)) {
            mkdir($file_path);
        }
        $data = []; //数组形式获取表格数据
        for ($i = 2; $i <= $row_num; $i++) {
            $data[$i]['name'] = $sheet->getCell("A" . $i)->getValue();
            $data[$i]['grade'] = $sheet->getCell("B" . $i)->getValue();
            $data[$i]['number'] = $sheet->getCell("C" . $i)->getValue();
            $data[$i]['group'] = $sheet->getCell("D" . $i)->getValue();
            $grade = $this->text2Img($arr, $data[$i], $i);
            $this->mergeImg(Env::get('root_path') . $arr['cert_img'], $grade);
        }
        return true;
    }

    public function mergeImg($cert_img, $text_img)
    {
        //案例一：将活动背景图片和动态二维码图片合成一张图片
        //创建图片对象
        $width = $this->canvas['merge']['width'];
        $height = $this->canvas['merge']['height'];

        $target_image = imagecreatetruecolor($width, $height);//设置画布
        $hec_image = imagecreatetruecolor($width, $height);//设置画布

        $bg1 = imagecolorallocatealpha($hec_image, 51, 51, 51, 127);//
        imagealphablending($hec_image, true);//关闭混合模式，以便透明颜色能覆盖原画板
        imagefill($hec_image, 0, 0, $bg1);//填充
        imagesavealpha($hec_image, true);//设置保存PNG时保留透明通道信息
        $bigImg = imagecreatefromstring(file_get_contents($cert_img));
        $qCodeImg = imagecreatefromstring(file_get_contents($text_img));
        $source['size'] = getimagesize($cert_img);
        $text_img1['size'] = getimagesize($text_img);
        // 缩放
        imagecopyresampled($target_image, $bigImg, 0, 0, 0, 0, $width, $height, $source['size'][0],
            $source['size'][1]);
        // 缩放
        imagecopyresampled($hec_image, $qCodeImg, 0, 0, 0, 0, $width, $height, $text_img1['size'][0],
            $text_img1['size'][1]);
        imagecopy($target_image, $hec_image, 30, 30, 0, 0, $width, $height);
        imagepng($target_image, $text_img);

    }
    public function text2Img($arr, $date, $i)
    {
        header("Content-type: image/png");
        $name = $date['name'];
        $grade = $date['grade'];
        $number = $date['number'];
        $group = $date['group'];
        $size = 60;//文字大小
        $font = Env::get('root_path') . "msyh.ttf";//字体
        $slimg = imagecreatetruecolor($this->canvas['text']['width'], $this->canvas['text']['height']);//建立一个画板，尺寸可以自行修改
        $bg = imagecolorallocatealpha($slimg, 0, 0, 0, 127);
        $color = imagecolorallocate($slimg, $this->canvas['text']['color']['red'], $this->canvas['text']['color']['green'], $this->canvas['text']['color']['blue']); //字体拾色
        imagealphablending($slimg, false);//关闭混合模式，以便透明颜色能覆盖原画板
        imagefill($slimg, 0, 0, $bg);//填充
        //姓名+成绩
        if ($arr['cert_type'] == 1) {
            imagefttext($slimg, $size, 0, $this->canvas['text']['type'][0]['name']['x'], $this->canvas['text']['type'][0]['name']['y'], $color, $font, $name);
            imagefttext($slimg, $size, 0, $this->canvas['text']['type'][0]['grade']['x'], $this->canvas['text']['type'][0]['grade']['y'], $color, $font, $grade);
        }
        //号码+成绩
        if ($arr['cert_type'] == 2) {
            imagefttext($slimg, $size, 0, $this->canvas['text']['type'][1]['number']['x'], $this->canvas['text']['type'][1]['number']['y'], $color, $font, $number);
            imagefttext($slimg, $size, 0, $this->canvas['text']['type'][1]['grade']['x'], $this->canvas['text']['type'][1]['grade']['y'], $color, $font, $grade);
        }
        //姓名+号码+成绩
        if ($arr['cert_type'] == 3) {
            imagefttext($slimg, $size, 0, $this->canvas['text']['type'][2]['name']['x'], $this->canvas['text']['type'][2]['name']['y'], $color, $font, $name);
            imagefttext($slimg, $size, 0, $this->canvas['text']['type'][2]['number']['x'], $this->canvas['text']['type'][2]['number']['y'], $color, $font, $number);
            imagefttext($slimg, $size, 0, $this->canvas['text']['type'][2]['grade']['x'], $this->canvas['text']['type'][2]['grade']['y'], $color, $font, $grade);
        }
        //组别+姓名+号码+成绩
        if ($arr['cert_type'] == 4) {
            imagefttext($slimg, $size, 0, $this->canvas['text']['type'][3]['grade']['x'], $this->canvas['text']['type'][3]['grade']['y'], $color, $font, $grade);
            imagefttext($slimg, $size, 0, $this->canvas['text']['type'][3]['group']['x'], $this->canvas['text']['type'][3]['group']['y'], $color, $font, $group);
            imagefttext($slimg, $size, 0, $this->canvas['text']['type'][3]['name']['x'], $this->canvas['text']['type'][3]['name']['y'], $color, $font, $name);
            imagefttext($slimg, $size, 0, $this->canvas['text']['type'][3]['number']['x'], $this->canvas['text']['type'][3]['number']['y'], $color, $font, $number);
        }
        imagesavealpha($slimg, true);
        header("content-type:image/png");
//        is_dir() 、mkdir()
        $file_path = Env::get('root_path') . 'userfiles' . DIRECTORY_SEPARATOR . 'cert' . DIRECTORY_SEPARATOR . $arr['cert_file'];

        $path = $number ? $number : $i;
        $img_path = $file_path . DIRECTORY_SEPARATOR . $path . '.png';

        imagepng($slimg, $img_path);
        imagedestroy($slimg);
        return $img_path;
    }

    /**
     * 压缩文件
     * @param string $path 压缩文件绝对路径
     * @param  $zip = new \ZipArchive(); 实例化
     * @param string $sub_dir 生成压缩文件里的文件夹
     */
    public function addFileToZip($path, $zip, $sub_dir = '')
    {
        $handler = opendir($path); //打开当前文件夹由$path指定。
        while (($filename = readdir($handler)) !== false) {
            if ($filename != "." && $filename != "..") {
                //文件夹文件名字为'.'和‘..'，不要对他们进行操作
                if (is_dir($path . "/" . $filename)) {
                    // 如果读取的某个对象是文件夹，则递归
                    $this->addFileToZip($path . "/" . $filename, $zip);

                } else {
                    //将文件加入zip对象
                    $zip->addFile($path . "/" . $filename, $sub_dir . $filename);
                }
            }

        }
        @closedir($path);
    }

    /**
     * 获取证书模板
     * @return string $file 模板excel的相对路径
     */
    public function getCertTemplate()
    {
        $act = input('get.act');
        $file = '';
        if ($act == 'excel') {
            $file = $_SERVER['HTTP_ORIGIN'] . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'template' . DIRECTORY_SEPARATOR . 'excel_template.xlsx';
        }
        if ($act == 'cert') {
            $file = $_SERVER['HTTP_ORIGIN'] . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'template' . DIRECTORY_SEPARATOR . 'cert.zip';
        }
        $json['status'] = 1;
        $json['message'] = lang('success');
        $json['file'] = $file;
        echo json_encode($json);
        return;
    }

    /**
     * 获取压缩文件
     * @return string $file 压缩文件的相对路径
     */
    public function getCertZip()
    {
        $cert_file = input('post.cert_file');//需要压缩的文件夹

        $file = DIRECTORY_SEPARATOR . 'userfiles' . DIRECTORY_SEPARATOR . 'cert' . DIRECTORY_SEPARATOR . $cert_file . '.zip';
        $filename = Env::get('root_path') . $file;
        $path = Env::get('root_path') . 'userfiles' . DIRECTORY_SEPARATOR . 'cert' . DIRECTORY_SEPARATOR . $cert_file;
        // 如果存在压缩文件，删除
        if (file_exists($filename)) {
            unlink($filename);
        }
        $zip = new \ZipArchive();
        // CREATE，此选项表示每次压缩时都是追加，不是覆盖，如果事先压缩文件不存在会自动创建
        if ($zip->open($filename, \ZIPARCHIVE::CREATE) !== true) {
            $json['status'] = 0;
            $json['message'] = lang('success');
        }
        $this->addFileToZip($path, $zip, 'download/');
        // 关闭
        $zip->close();
        //检查文件或目录是否存在
        if (!file_exists($filename)) {
            $json['status'] = 0;
            $json['message'] = lang('fail');
        }
        $json['status'] = 1;
        $json['message'] = lang('success');
        $json['file'] = $file;
        echo json_encode($json);
        return;
    }

    /**
     * 删除目录下所有文件
     * @param  string $dir 文件夹
     */
    function delDir($dir)
    {
        $dh = opendir($dir);
        while ($file = readdir($dh)) {
            if ($file != "." && $file != "..") {
                $path = $dir . "/" . $file;
                if (!is_dir($path)) {
                    unlink($path);
                } else {
                    $this->delDir($path);
                }
            }
        }
        closedir($dh);
    }

}

?>
